#ifndef _TCP_SERVER_H_
#define _TCP_SERVER_H_


#include <iostream>
#include <string>         //string
#include <cstdlib>        //exit
#include <cstring>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

//using namespace std;一般代码量少的时候用，多用于源文件，防止命名冲突
#define BACKLOG 5

class tcpServer
{
    private:
        int port;
        int lsock;    //TCP中sock应该叫为listen_sock,简化写成lsock
    public:
        tcpServer(int _port):port(_port),lsock(-1)
        {}
        void initServer()
        {
            lsock = socket(AF_INET, SOCK_STREAM, 0);
            if(lsock < 0)
            {
                std::cerr << "lsock error" << std::endl;    //建议以后错误信息往日志里写
                exit(2);
            }
            struct sockaddr_in local;
            local.sin_family = AF_INET;
            local.sin_port = htons(port);
            local.sin_addr.s_addr = htonl(INADDR_ANY);    //代码风格好
            if(bind(lsock, (struct sockaddr*)&local, sizeof(local)) < 0)
            {
                 std::cerr << "bind error" << std::endl;
                 exit(3);  
            }
            if(listen(lsock,BACKLOG) < 0)
            {
                std::cerr << "bind error" << std::endl;
                exit(4);
            }
        }
        void service(int sock)
        {
            char buffer[1024];
            while(true)
            {
                //read或write都可
                ssize_t s = recv(sock, buffer, sizeof(buffer) - 1, 0);
                if(s > 0)
                {
                    buffer[s] = 0;
                    std::cout << "Client #" << buffer << std::endl;

                    send(sock, buffer, strlen(buffer), 0);
                }

           }
        }
        void start()
        {
            struct sockaddr_in endpoint;
            while(true)
            {
                socklen_t len = sizeof(endpoint);
                int sock = accept(lsock,(struct sockaddr*)&endpoint,&len);
                if(sock < 0)
                {
                     std::cerr << "accept error" << std::endl;
                     continue;
                }
                std::cout << "get a new link..." << std::endl; // 看到有人连上我的标识
                service(sock);
            }
        }
        ~tcpServer()
        {}
};

#endif
